home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / DYN401.ZIP / threads / semaphor.d < prev    next >
Text File  |  1996-02-04  |  4KB  |  213 lines

  1.  
  2.  
  3.  
  4.  
  5. /*
  6.  *
  7.  *    Copyright (c) 1993-1996 Algorithms Corporation
  8.  *    3020 Liberty Hills Drive
  9.  *    Franklin, TN  37067
  10.  *
  11.  *    ALL RIGHTS RESERVED.
  12.  *
  13.  *
  14.  *
  15.  */
  16.  
  17.  
  18. #include <string.h>
  19.  
  20.  
  21. defclass  Semaphore  {
  22.     object    iObj;            /*  main object pointer    */
  23.     char    *iName;            /*  semaphore name    */
  24.     int    iCount;
  25.     int    iMaximum;
  26.     object    iWaiting_threads;    /*  LinkObject of waiting threads */
  27.     struct _Semaphore_iv_t *iNext;    /*  linked list of semaphores    */
  28.  class:
  29.     struct _Semaphore_iv_t *cMsl;    /*  master semaphore list    */
  30. };
  31.  
  32.  
  33.  
  34. cmeth    gNewSemaphore, <vNew> : New (object self, char *name, int cnt, int mx)
  35. {
  36.     object    obj = gNew(super);
  37.     ivType    *iv = ivPtr(obj);
  38.     
  39.     iObj = obj;
  40.     if (name)  {
  41.         iName = Tnalloc(char, strlen(name)+1);
  42.         strcpy(iName, name);
  43.     }
  44.     iCount = cnt;
  45.     iMaximum = mx;
  46.     iNext = cMsl;
  47.     cMsl = iv;
  48.     return obj;
  49. }
  50.  
  51. cmeth    gNew()
  52. {
  53.     return New(self, NULL, 1, 1);
  54. }
  55.         
  56. imeth    int    gWaitFor(object self)
  57. {
  58.     object    ct;
  59.  
  60.     INHIBIT_THREADER;
  61.     if (!(ct = gFindStr(Thread, NULL)))  {
  62.         ENABLE_THREADER;
  63.         return 0;
  64.     }
  65.     if (iCount)  {
  66.         iCount--;
  67.         ENABLE_THREADER;
  68.         return 0;
  69.     }
  70.     gWaitSemaphore(ct, self);
  71.     
  72.     if (!iWaiting_threads)
  73.         iWaiting_threads = gNew(LinkObject);
  74.     gAddLast(iWaiting_threads, ct);
  75.     ENABLE_THREADER;
  76.  
  77.     __dynace_yield();
  78.     return 0;
  79. }
  80.  
  81. imeth    gRelease : Release (object self, int cnt)
  82. {
  83.     object    thread;
  84.  
  85.     iCount += cnt;
  86.     if (iCount > iMaximum)
  87.         iCount = iMaximum;
  88.     INHIBIT_THREADER;
  89.     while (iCount  &&  iWaiting_threads  &&  (thread = gFirst(iWaiting_threads)))  {
  90.         gDisposeFirst(iWaiting_threads);
  91.         gReleaseSemaphore(thread);
  92.         iCount--;
  93.     }
  94.     ENABLE_THREADER;
  95.     return self;
  96. }
  97.  
  98. imeth    object    gDispose, gDeepDispose (object self)
  99. {
  100.     ivType    *t, *p;
  101.     
  102.     INHIBIT_THREADER;
  103.     while (iWaiting_threads  &&  gFirst(iWaiting_threads))
  104.         Release(self, iMaximum);
  105.     if (iWaiting_threads)
  106.         gDispose(iWaiting_threads);
  107.     if (iName)
  108.         free(iName);
  109.     for (p=NULL, t=cMsl ; t ; p=t, t=t->iNext)
  110.         if (t == iv)  {
  111.             if (p)
  112.                 p->iNext = t->iNext;
  113.             else
  114.                 cMsl = t->iNext;
  115.             break;
  116.         }
  117.     gDispose(super);
  118.     ENABLE_THREADER;
  119.     return NULL;
  120. }
  121.  
  122. imeth    object    gGCDispose(object self)
  123. {
  124.     ivType    *t, *p;
  125.     
  126.     INHIBIT_THREADER;
  127.     if (iWaiting_threads  &&  gFirst(iWaiting_threads))  {
  128.         ENABLE_THREADER;
  129.         return NULL;
  130.     }
  131.     if (iName)
  132.         free(iName);
  133.     for (p=NULL, t=cMsl ; t ; p=t, t=t->iNext)
  134.         if (t == iv)  {
  135.             if (p)
  136.                 p->iNext = t->iNext;
  137.             else
  138.                 cMsl = t->iNext;
  139.             break;
  140.         }
  141.     gDispose(super);
  142.     ENABLE_THREADER;
  143.     return NULL;
  144. }
  145.  
  146. cmeth    gFindStr, <vFind> (object self, char *name)
  147. {
  148.     ivType    *iv;
  149.     
  150.     USE(self);
  151.     if (!name)
  152.         return NULL;
  153.     for (iv=cMsl ; iv ; iv=iNext)
  154.         if (iName  &&  !strcmp(iName, name))
  155.             return iObj;
  156.     return NULL;
  157. }
  158.  
  159. imeth    int    gCount(object self)
  160. {
  161.     return iCount;
  162. }
  163.  
  164. imeth    char    *gName(object self)
  165. {
  166.     return iName;
  167. }
  168.  
  169. /*  the following method is used by the threader  */
  170.  
  171. imeth    gRemoveWaits(object self, object thrd)
  172. {
  173.     object    linkSequence, linkValue, thread;
  174.  
  175.     if (!iWaiting_threads)
  176.         return self;
  177.     INHIBIT_THREADER;
  178.     linkSequence = gSequenceLinks(iWaiting_threads);
  179.     while (linkValue = gNext(linkSequence))  {
  180.         thread = gValue(linkValue);
  181.         if (thread == thrd)  {
  182.             gDispose(linkValue);
  183.             break;
  184.         }
  185.     }
  186.     if (linkValue)
  187.         gDispose(linkSequence);
  188.     ENABLE_THREADER;
  189.     return self;
  190. }
  191.  
  192. imeth    gCopy, gDeepCopy (object self)
  193. {
  194.     return gShouldNotImplement(self, "Copy/DeepCopy");
  195. }
  196.  
  197.  
  198.  
  199.  
  200. /*
  201.  *
  202.  *    Copyright (c) 1993-1996 Algorithms Corporation
  203.  *    3020 Liberty Hills Drive
  204.  *    Franklin, TN  37067
  205.  *
  206.  *    ALL RIGHTS RESERVED.
  207.  *
  208.  *
  209.  *
  210.  */
  211.  
  212.  
  213.